package edu.yngsxy.wkstudy.core.controller;

import edu.yngsxy.wkstudy.core.model.common.Result;
import edu.yngsxy.wkstudy.core.model.dto.BaseQueryDTO;
import edu.yngsxy.wkstudy.core.model.entity.WkBaseEntity;
import edu.yngsxy.wkstudy.core.service.WkBaseService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.web.bind.annotation.*;

/**
 * 通用基础控制器
 *
 * @param <E>         实体类类型
 * @param <VO>        响应VO类型
 * @param <AddDTO>    新增操作的DTO类型
 * @param <UpdateDTO> 更新操作的DTO类型
 * @param <S>         服务类类型
 */
public abstract class WkBaseController<
        E extends WkBaseEntity,
        VO,
        AddDTO,
        UpdateDTO,
        S extends WkBaseService<E>> {

    protected final S service;

    // 构造方法注入服务类（必须由子类调用）
    public WkBaseController(S service) {
        this.service = service;
    }

/**
 * 分页查询（返回VO分页结果）  */
@GetMapping("/list")
@Operation(summary = "分页查询", description = "支持分页参数和条件筛选")
public Result<IPage<VO>> list(@Valid  @ParameterObject BaseQueryDTO query) {
    IPage<E> entityPage = service.selectPage(query.getPageNum(), query.getPageSize());
    System.out.println("分页;"+query.getPageNum());
    System.out.println(query.getPageSize());
    // 将实体分页结果转换为VO分页结果（需子类实现转换逻辑）
    IPage<VO> voPage = entityPage.convert(this::convertToVO);
    return Result.success(voPage);
}

    /**
     * 根据ID查询（返回VO）
     */
    @GetMapping("/get/{id}")
    @Operation(summary = "根据ID查询", description = "查询单条数据详情")
    public Result<VO> get(@PathVariable Long id) {
        E entity = service.getById(id);
        if (entity == null) {
            return Result.error("数据不存在，ID：" + id);
        }
        return Result.success(convertToVO(entity));
    }

    /**
     * 新增数据（接收AddDTO）
     */
    @PostMapping("/add")
    @Operation(summary = "新增数据", description = "新增一条记录")
    public Result<Boolean> add(@RequestBody @Valid AddDTO addDTO) {
        E entity = convertAddDTOToEntity(addDTO); // 将DTO转换为实体
        return Result.success(service.save(entity));
    }

    /**
     * 更新数据（接收UpdateDTO）
     */
    @PutMapping("/update")
    @Operation(summary = "更新数据", description = "根据ID更新记录")
    public Result<Boolean> update(@RequestBody @Valid UpdateDTO updateDTO) {
        E entity = convertUpdateDTOToEntity(updateDTO); // 将DTO转换为实体
        return Result.success(service.updateById(entity)); }

    /**
     * 根据ID删除
     */
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "根据ID删除", description = "逻辑删除或物理删除单条记录")
    public Result<Boolean> delete(@PathVariable Long id) {
        return Result.success(service.removeById(id));
    }

    // ------------------------------ 抽象方法：由子类实现转换逻辑 ------------------------------

    /**
     * 将实体转换为VO（子类必须实现，用于响应前端）
     * <p>默认实现仅支持 VO 与 E 类型相同的场景，否则会抛出 ClassCastException</p>
     */
    protected VO convertToVO(E entity) {
        return (VO) entity;
    }
    ;

    /**
     * 将新增DTO转换为实体（子类实现）
     * <p>默认实现仅支持 AddDTO 与 E 类型相同的场景，否则会抛出 ClassCastException</p>
     */
    protected E convertAddDTOToEntity(AddDTO addDTO) {
        return (E) addDTO;
    }
    ;
    /**
     * 将更新DTO转换为实体（子类实现）
     * <p>默认实现仅支持 UpdateDTO 与 E 类型相同的场景，否则会抛出 ClassCastException</p>
     */
    protected E convertUpdateDTOToEntity(UpdateDTO updateDTO) {
        return (E) updateDTO;
    }
}